import 'package:flutter_1800/models/ChatMessage.dart';
import 'package:flutter_1800/models/Session.dart';
import 'package:flutter_1800/tools/AppUtil.dart';
import 'package:flutter_1800/tools/event_bus.dart';
import 'package:flutter_1800/tools/storage.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

class DBUtil {
  static init() async {
    final Future<Database> database = openDatabase(
        //获取数据库对象
        join(await getDatabasesPath(), 'chat_database14.db'),
        onCreate: (db, version) {
      // Run the CREATE TABLE statement on the database.
      return db.execute(
        "CREATE TABLE chatmessage14(id text, to_account TEXT, from_account TEXT,chattype INTEGER, content TEXT, red TEXT,time TEXT,from_avatar TEXT,from_nickname TEXT,msg_type INTEGER,type INTEGER,read INTEGER);",
      );
    }, version: 1);
    return database;
  }

  static Future<void> insertChatmessage(ChatMessage chatMessage) async {
    // Get a reference to the database.
    final Database db = await init();

    final List<Map<String, dynamic>> one = await db.query(
      'chatmessage14',
      where: "id='" + chatMessage.id.toString() + "'",
    );
    if (one.isNotEmpty) {
      return;
    }

    var res = await db.insert(
      'chatmessage14',
      chatMessage.toMap(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
    List sessions = await StorageUtil.getSessions(AppUtil.user!.account!);
    Session? session = sessions.firstWhere(
        (element) =>
            element.account == AppUtil.user!.account! &&
            (chatMessage.type == 0
                ? element.to_account == chatMessage.to_account ||
                    element.to_account == chatMessage.from_account
                : element.to_account == chatMessage.groupAccount),
        orElse: () => null);
    if (session != null) {
      session.time = AppUtil.formateTime();
      session.account = AppUtil.user!.account;
      session.content = chatMessage.content;
      session.type = chatMessage.type;
      session.avatar = chatMessage.from_avatar;
      session.action = chatMessage.action;
      session.nickname = chatMessage.from_nickname;
      session.msg_type = chatMessage.msg_type;
    } else {
      session = Session(
          to_account: chatMessage.type == 1
              ? chatMessage.groupAccount
              : (chatMessage.to_account == AppUtil.user!.account!
                  ? chatMessage.from_account
                  : chatMessage.to_account),
          account: AppUtil.user!.account!,
          nickname: chatMessage.from_nickname,
          avatar: chatMessage.from_avatar,
          time: chatMessage.time,
          type: chatMessage.type,
          action: chatMessage.action,
          msg_type: chatMessage.msg_type,
          content: chatMessage.content);
      sessions.add(session);
    }
    if (chatMessage.type == 1) {
      session.nickname = chatMessage.groupName;
      session.avatar = chatMessage.groupAvatar;
    }
    StorageUtil.saveSessions(sessions, AppUtil.user!.account!);

    eventBus.fire(SocketEvent({}));

    //await updateSession(chatMessage);
  }

  static delChatMessage(String id) async {
    // Get a reference to the database.
    final Database db = await init();

    // Query the table for all The Dogs.

    await db.delete('chatmessage14', where: "id='" + id + "'");
  }

  static delQunChatMessage(String account) async {
    // Get a reference to the database.
    final Database db = await init();

    await db.delete('chatmessage14',
        where: "to_account='" + account + "' and type=1");
  }

  static delUserChatMessage(String account) async {
    // Get a reference to the database.
    final Database db = await init();

    // Query the table for all The Dogs.

    await db.delete('chatmessage14',
        where: "to_account='" + account + "' and type=0");
  }

  static Future<List<ChatMessage>> searchChatMessage(String text) async {
    // Get a reference to the database.
    final Database db = await init();

    // Query the table for all The Dogs.
    final List<Map<String, dynamic>> maps = await db.query('chatmessage14',
        where: "content like '%" + text + "%'",
        offset: 0,
        orderBy: "time desc",
        limit: 100);

    // Convert the List<Map<String, dynamic> into a List<Dog>.
    return List.generate(maps.length, (i) {
      return ChatMessage(
        to_account: maps[i]['to_account'],
        from_account: maps[i]['from_account'],
        chattype: maps[i]['chattype'],
        content: maps[i]['content'],
        time: maps[i]['time'],
        type: maps[i]['type'],
        msg_type: maps[i]['msg_type'],
        from_avatar: maps[i]['from_avatar'],
        from_nickname: maps[i]['from_nickname'],
        id: maps[i]['id'],
        read: maps[i]['read'],
      );
    });
  }

  static Future<List<ChatMessage>> queryChatMessage(
      String myAccount, String otherAccount, int type) async {
    final Database db = await init();

    // Query the table for all The Dogs.
    final List<Map<String, dynamic>> maps = await db.query('chatmessage14',
        where: type == 0
            ? " (to_account='" +
                myAccount +
                "' and from_account='" +
                otherAccount +
                "') or (to_account='" +
                otherAccount +
                "' and from_account='" +
                myAccount +
                "')"
            : "to_account='" + otherAccount + "'",
        offset: 0,
        orderBy: "time desc",
        limit: 100);

    // Convert the List<Map<String, dynamic> into a List<Dog>.
    return List.generate(maps.length, (i) {
      return ChatMessage(
        to_account: maps[i]['to_account'],
        from_account: maps[i]['from_account'],
        chattype: maps[i]['chattype'],
        content: maps[i]['content'],
        time: maps[i]['time'],
        type: maps[i]['type'],
        msg_type: maps[i]['msg_type'],
        from_avatar: maps[i]['from_avatar'],
        from_nickname: maps[i]['from_nickname'],
        id: maps[i]['id'],
        read: maps[i]['read'],
      );
    });
  }

  static Future<int> queryTotalUnread() async {
    // Get a reference to the database.
    final Database db = await init();
    // Query the table for all The Dogs.
    final List<Map<String, dynamic>> maps = await db.query('chatmessage14',
        where: "read=0", offset: 0, orderBy: "time desc", limit: 100);
    // Convert the List<Map<String, dynamic> into a List<Dog>.
    return maps.length;
  }

  static Future<int> queryUnread(
      String myAccount, String otherAccount, int type) async {
    // Get a reference to the database.
    final Database db = await init();

    // Query the table for all The Dogs.
    final List<Map<String, dynamic>> maps = await db.query('chatmessage14',
        where: type == 0
            ? " (to_account='" +
                myAccount +
                "' and from_account='" +
                otherAccount +
                "') or (to_account='" +
                otherAccount +
                "' and from_account='" +
                myAccount +
                "')"
            : "to_account='" + otherAccount + "'" + " and read=0",
        offset: 0,
        orderBy: "time desc",
        limit: 100);

    // Convert the List<Map<String, dynamic> into a List<Dog>.
    return maps.length;
  }

  static Future<int> updateUnread(
      String myAccount, String otherAccount, int type) async {
    // Get a reference to the database.
    final Database db = await init();

    // Query the table for all The Dogs.
    final int v = await db.update('chatmessage14', {"read": 1},
        where: type == 0
            ? " (to_account='" +
                myAccount +
                "' and from_account='" +
                otherAccount +
                "') or (to_account='" +
                otherAccount +
                "' and from_account='" +
                myAccount +
                "')"
            : "to_account='" + otherAccount + "'");

    // Convert the List<Map<String, dynamic> into a List<Dog>.
    return v;
  }
}
